package org.yray.sip.server;


import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.socket.DatagramPacket;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.yray.sip.base.SipMsg;
import org.yray.sip.handler.MessageHandler;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.InputStreamReader;
import java.net.InetSocketAddress;

@Slf4j
public class SipServerHandler extends SimpleChannelInboundHandler<DatagramPacket> {

    private Channel channel;

    private final SipServerContext sipServerContext;


    public SipServerHandler(SipServerContext sipServerContext)
    {
        this.sipServerContext=sipServerContext;
        sipServerContext.setSipServerHandler(this);
    }

    public SipServerContext getServerContext() {
        return sipServerContext;
    }


    public Channel getChannel() {
        return channel;
    }

    public void setChannel(Channel channel) {
        this.channel = channel;
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        //关闭之后会导致netty不可用，udp是单通道的 尽量防止异常抛到这里
        ctx.close();
        log.error(cause.getMessage(), cause);
    }

    //发送udp数据包 注意gbk编码
    public void send(String msg, InetSocketAddress sender) {
        ByteBuf byteBuf = Unpooled.copiedBuffer(msg.getBytes());
        channel.writeAndFlush(new DatagramPacket(byteBuf, sender));
        //log.debug("send to {},{}", sender.getAddress().getHostAddress(), sender.getPort());
        //log.info("----send----{}:{}----------------------------------------",sender.getAddress().getHostAddress(),sender.getPort());
        log.info("send={}", msg);
    }

    public void sendToSipServer(SipSession sipSession,String msg)
    {
        sipSession.addSipMsg(msg);
        send(msg, sipServerContext.getSipServerAddr());
    }

    @Override
    protected void channelRead0(ChannelHandlerContext channelHandlerContext, DatagramPacket packet) throws Exception {
        {
            //去除空包，公网状态下很多空包 应该是服务器端口被探测
            InetSocketAddress sender = packet.sender();
            log.info(" ----receive----{}:{}---------------------------------------------",sender.getAddress().getHostAddress(), sender.getPort());
            if (packet.content().readableBytes() < 5) {
                return;
            }
            byte[] data = new byte[packet.content().readableBytes()];
            packet.content().readBytes(data);
            try {
                BufferedReader br = new BufferedReader(new InputStreamReader(new ByteArrayInputStream(data)));
                SipMsg sipMsg = SipMsg.newSipMsg().bufferedReader(br).build();
                sipMsg.setReceiveIp(sender.getAddress().getHostAddress());
                sipMsg.setReceivePort(sender.getPort());
                String[] resp = MessageHandler.doMess(sipMsg,sipServerContext);
                for (String str : resp) {
                    send(str, sender);
                }

            } catch (Exception e) {
                log.error("Exception:{}", ExceptionUtils.getStackTrace(e));
                //throw e;
            }

        }

    }
}

